package com.thinkit.bigdata.web.security;

import com.thinkit.bigdata.web.model.config.SysResource;
import com.thinkit.bigdata.web.model.sec.SysRole;
import com.thinkit.bigdata.web.model.sec.User;
import com.thinkit.bigdata.web.service.sec.PermissionService;
import com.thinkit.bigdata.web.service.sec.RoleService;
import com.thinkit.bigdata.web.service.sec.UserService;
import org.apache.log4j.Logger;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

/**
 * 用户身份验证,授权 Realm 组件
 *
 * @author StarZou
 * @since 2014年6月11日 上午11:35:28
 **/
@Component(value = "securityRealm")
public class SecurityRealm extends AuthorizingRealm {

    private static Logger logger = Logger.getLogger(SecurityRealm.class);

    @Resource
    private UserService userService;

    @Resource
    private RoleService roleService;

    @Resource
    private PermissionService permissionService;

    /**
     * 权限检查
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        String username = String.valueOf(principals.getPrimaryPrincipal());

        final User user = userService.selectByUsername(username);
        final List<SysRole> roleInfos = roleService.selectRoleByUserId(user.getId());
        for (SysRole role : roleInfos) {
            // 添加角色
            logger.info("【" + user.getUsername() + "】对应的角色为【" + role.getName() + "】");
            authorizationInfo.addRole(role.getName());
            StringBuilder sb = new StringBuilder();
            final List<SysResource> permissions = permissionService.selectPermissions(role.getId());
            for (SysResource resource : permissions) {
                // 添加权限
                authorizationInfo.addStringPermission(resource.getCode());
                sb.append(resource.getName()).append(",");
            }
            logger.info("【" + role.getName() + "】对应的权限有【" + sb.toString() + "】");
        }
        return authorizationInfo;
    }

    /**
     * 登录验证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
        String username = String.valueOf(token.getPrincipal());
        String password = new String((char[]) token.getCredentials());
        // 通过数据库进行验证
        Md5Hash hash = new Md5Hash(password, "加盐", 2);//散裂2次
        final User authentication = userService.authentication(new User(username, hash.toString()));
        if (authentication == null) {
            throw new AuthenticationException("用户名或密码错误.");
        }
        return new SimpleAuthenticationInfo(username, password, getName());
    }
}
